package com.qfedu.lc.server.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qfedu.lc.common.config.RabbitKeyConfig;
import com.qfedu.lc.common.config.RedisKeyConfig;
import com.qfedu.lc.common.param.GrowthAdd;
import com.qfedu.lc.common.param.MqMsg;
import com.qfedu.lc.common.param.UserAdd;
import com.qfedu.lc.common.param.UserLogin;
import com.qfedu.lc.common.util.JwtUtil;
import com.qfedu.lc.common.vo.R;
import com.qfedu.lc.server.entity.User;
import com.qfedu.lc.server.entity.UserLog;
import com.qfedu.lc.server.mapper.UserLogMapper;
import com.qfedu.lc.server.mapper.UserMapper;
import com.qfedu.lc.server.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.sf.jsqlparser.statement.select.KSQLWindow;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 1.用户表 服务实现类
 * </p>
 *
 * @author wgz
 * @since 2023-10-30
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private StringRedisTemplate template;

    @Resource
    private UserMapper userMapper;

    @Resource
    private UserLogMapper userLogMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public R registerUser(UserAdd userAdd,String ip) {

        // 1.判断参数是否为 空
        if (userAdd==null || StrUtil.hasEmpty(userAdd.getAccount(),userAdd.getCode(),userAdd.getPassword(),userAdd.getPhone())){
            return R.fail("请检查用户数据");
        }
        //  2.判断验证码 是否匹配
        String key  = RedisKeyConfig.SMS_RCODE + userAdd.getPhone();
        // 比较redis中对应手机号验证码 和  提交的验证码比较
        if (!userAdd.getCode().equals( template.opsForValue().get(key))){
            return R.fail("验证码错误");
        }

        // 3.判断用户手机号 是否存在
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("phone",userAdd.getPhone());

        User user = userMapper.selectOne(userQueryWrapper);
        if (user!=null){
            return R.fail("该用户于已存在");
        }
        // 4. 插入用户

        // SecureUtil.md5(add.getPassword()) 对密码获取md5
        //SecureUtil.sha256(SecureUtil.md5(add.getPassword())) 对md5 再取hash值
        User insertUser = new User(userAdd.getPhone(),userAdd.getAccount(),SecureUtil.sha256( SecureUtil.md5(userAdd.getPassword())),1,new Date());
        if (userMapper.insert(insertUser) ==0){
            // 插入失败
            return  R.fail("注册用户失败");
        }

        // 5.记录用户注册的日志      insertUser.getId()自增id 在插入时会自动返回
        userLogMapper.insert(new UserLog(insertUser.getId(),"注册",ip,"注册用户",userAdd.getPhone(),new Date()));

        // 6.删除验证码
        template.delete(key);


        // 7. 发送积分成长的队列
        GrowthAdd growthAdd = new GrowthAdd(insertUser.getId(), "注册", 50);
        rabbitTemplate.convertAndSend("", RabbitKeyConfig.Q_USER_GROWTH,
                new MqMsg( IdUtil.getSnowflakeNextId(),5,growthAdd
                        ));

        return R.ok("注册成功，请登录");
    }

    @Override
    public R loginPass(UserLogin userLogin,String ip) {

        // 1.判断参数是否为空
        if (userLogin==null || StrUtil.hasEmpty(userLogin.getName(),userLogin.getPass())){
            return R.fail("用户信息错误");

        }
        // 2.判断账户是否存在
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("account",userLogin.getName());

        User user = userMapper.selectOne(userQueryWrapper);

        if (user==null){ // 没有用户
            return R.fail("该用户未注册");
        }
        if (user.getStatus()!=1){
            return R.fail("该用户不可用");
        }

        // 3.判断账户名 密码 是否匹配

        if (!user.getPassword().equals(SecureUtil.sha256(SecureUtil.md5(userLogin.getPass())))){
            return R.fail("请输入正确的密码");
        }

        // 4. 该手机号对应账户的次数 是否 超过3次
        // 获取对应手机号登录的的记录  RedisKeyConfig.LOGIN_UID_TOKEN+user.getPhone()
        Set<String> keys = template.keys(RedisKeyConfig.LOGIN_UID_TOKEN + user.getPhone() + "*");
        if (keys.size()>=3){ // 登录次数超过3次
            return R.fail("登录超过3次，请退出其他客户端，再次重试");
        }

        // 5.生成 jwt token
        String token = JwtUtil.createJwt(user.getId(), user.getAccount(), user.getPhone());
        //       redis 记录
        //       <token,用户对象>    记录用户信息
        template.opsForValue().set(RedisKeyConfig.LOGIN_TOKEN+token, JSONUtil.toJsonStr(user),RedisKeyConfig.LOGIN_TOKEN_TIME, TimeUnit.SECONDS);

        //       <手机号+token,"时间">  记录手机号登录的次数
        template.opsForValue().set(RedisKeyConfig.LOGIN_UID_TOKEN+user.getPhone()+":"+token,System.currentTimeMillis()+"",RedisKeyConfig.LOGIN_TOKEN_TIME, TimeUnit.SECONDS);


        // 5.1   首次登录  积分成长
        QueryWrapper<UserLog> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",user.getId());
        queryWrapper.eq("type","登录");

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        // 得到今日的年月日
        String time = dateFormat.format(new Date());

        queryWrapper.gt("ctime" ,time);

        // 查询大于今日 零点零分零秒的的登录记录 如果有，说明当前登录就不是首次登录
        List<UserLog> userLogs = userLogMapper.selectList(queryWrapper);
        if (userLogs==null || userLogs.isEmpty()){
            GrowthAdd growthAdd = new GrowthAdd(user.getId(), "登录", 2);

            rabbitTemplate.convertAndSend("", RabbitKeyConfig.Q_USER_GROWTH,
                    new MqMsg( IdUtil.getSnowflakeNextId(),5,growthAdd
                    ));
        }


        // 6.写入用户日志
        userLogMapper.insert(new UserLog(user.getId(),"注册",ip,"注册用户",user.getPhone(),new Date()));

        // 7.返回 jwt token
        return R.ok(token);
    }
}
